﻿using System.Data.SqlClient;
using System;
using System.IO;
using Microsoft.DirectX.AudioVideoPlayback;
using System.Windows.Threading;
using System.Windows;
using System.Management;
using Microsoft.DirectX.DirectSound;
using System.Threading;
using System.ComponentModel;

namespace SoundServant
{
    public partial class Recorder
    {
        // General
        StoredRecording recording;
        BackgroundWorker buttonLockout;
        SqlConnection dbConnection;
        Congregation congregation;

        // Recorder
        bool auto = true;
        string recorderNextTrackTitle = "";
        string recorderNextTrackFile = "";
        bool recorderLocked = false;
        short recorderCurrentTrackNumber = 0;
        short recorderCurrentDiscNumber = 0;
        TimeSpan recorderTotalRecordingTime;
        TimeSpan recorderCurrentTrackTime;
        TimeSpan recorderCurrentDiscTime;
        RecorderStates recorderState;

        // Capture
        Thread captureThread;
        ThreadStart captureThreadStart;
        CaptureBufferDescription captureBufferDescription;
        CaptureBuffer captureBuffer;
        WaveFormat captureWaveFormat;
        Capture captureDevice;
        AutoResetEvent captureResetEvent;
        Notify captureNotify;
        object captureLockObject = new object();
        bool captureNewTrack = false;
        bool captureNewDisc = false;
        bool captureStopRecording = false;
        bool capturePaused = false;

        // KM Player
        SongStates songState;
        Audio songPlayer;
        int? songLoadTickTock = null;
        int songNumberPlayed = 0;
        int songLoaded;
        string songToLoad;
        string songLoadedTitle;
        string songLoadedScripture;
        const int songNumExpected = 3;

        // Song Player
        FileInfo[] musicFiles;
        MusicStates musicState;
        Audio musicPlayer;
        BackgroundWorker musicFader;
        int musicVolume;
        int musicCurrentTrack = 0;
        int musicNumberOfTracks;
        int musicSongbook;
        string musicSongbookName;

        public bool Auto { get { return auto; } set { auto = value; } }


        public delegate void VoidEventHandler();
        public event VoidEventHandler LockoutStarted;
        public event VoidEventHandler LockoutFinished;

        public Recorder()
        {
        }

        public void Initialize(Congregation c)
        {
            Logs.Information("Recorder", "Inializing");

            dbConnection = SS.Connection();
            congregation = c;

            recorderState = RecorderStates.Ready;
            buttonLockout = new BackgroundWorker();
            buttonLockout.WorkerSupportsCancellation = true;
            buttonLockout.DoWork += new DoWorkEventHandler(LockoutTimer);
            buttonLockout.RunWorkerCompleted += new RunWorkerCompletedEventHandler(LockoutEnded);

            musicVolume = Options.Default.MusicVolume;
            DirectoryInfo musicDir = new DirectoryInfo(Options.Default.BaseDirectory + "\\" + Options.Default.MusicDirectory);
            musicFiles = musicDir.GetFiles("*.mp3");
            musicNumberOfTracks = musicFiles.Length;
            Logs.Information("Background Music", "Number of MP3 Files Found: " + musicNumberOfTracks);
            musicSongbook = congregation.Songbook;
            musicSongbookName = congregation.SongbookName;

            ShuffleMusic();

            musicFader = new BackgroundWorker();
            musicFader.DoWork += new DoWorkEventHandler(MusicFader);
            musicFader.RunWorkerCompleted += new RunWorkerCompletedEventHandler(MusicFadeFinished);
            musicState = MusicStates.Ready;

            songState = SongStates.Ready;
            SS.TenthOfASecondTimer.Tick += new EventHandler(SongLoadTick);


        }

        public MeetingType GuessMeetingType()
        {
            MeetingType type = MeetingType.Special;
            if (DateTime.Now.DayOfWeek == congregation.BstmssmDay) { type = MeetingType.SchoolServiceMeeting; Logs.Information("Recorder", "Meeting Type Guessed: " + SS.FullMeetingType(type)); }
            else if (DateTime.Now.DayOfWeek == congregation.PtwsDay) { type = MeetingType.TalkWatchtowerStudy; Logs.Information("Recorder", "Meeting Type Guessed: " + SS.FullMeetingType(type)); }
            else
            {
                Logs.Information("Recorder", "Failed To Guess Meeting Type, showing \"What Meeting Prompt\"");
                WhatMeetingWindow whatMeetingWindow = new WhatMeetingWindow();
                type = whatMeetingWindow.WhatMeetingDialog();
                Logs.Information("Recorder", "Meeting Type Set To: " + SS.FullMeetingType(type));
            }
            Logs.Information("Recorder", "Meeting Type Guessed: " + SS.FullMeetingType(type));
            return type;
        }

        void LockButtons() { if (LockoutStarted != null) LockoutStarted(); recorderLocked = true; }
        void LockButtonsWithTimeOut() { LockButtons(); BeginLockOutTimer(); }
        void BeginLockOutTimer() { if (recorderLocked) if (!buttonLockout.IsBusy) { LockButtons(); buttonLockout.RunWorkerAsync(); } }
        void UnlockButtons() { if (LockoutFinished != null) LockoutFinished(); recorderLocked = false; }
        void LockoutEnded(object sender, RunWorkerCompletedEventArgs e) { UnlockButtons(); }
        void LockoutTimer(object sender, DoWorkEventArgs e) { Thread.Sleep(1000); }
    }

    public enum RecorderStates
    {
        Ready,
        Starting,
        Recording,
        Finished
    }

    public enum MusicStates
    {
        Ready,
        Playing,
        Skiping,
        Stopping
    }
    public enum SongStates
    {
        Ready,
        Loaded,
        Playing
    }
}
